from io import StringIO
from glob import iglob
import imp
import os
import logging

logger = logging.getLogger(__name__)

class Model:
	def __init__(self):
		self._parser_controller = ParserController()
		self._parser = None

	def parser_names(self):
		return self._parser_controller.parser_names()

	def set_parser(self, name, text):
		self._parser = self._parser_controller.get_parser(name, text)
		self._tokens = []
		# index of next token that should be shown
		self._next_token = 0

	def next_token(self):
		parser = self._parser
		if not parser: return None
		length = len(self._tokens)
		if self._next_token == length:
			# get new token from parser
			token = self._parser.next_token()
			if token is None: return None # no more tokens available
			self._tokens.append(token)
		else:
			token = self._tokens[self._next_token]
		self._next_token += 1
		return token

	def prev_token(self):
		# say next_token is 2, this means we're currently showing token 1
		# which means that the previous token is number 0
		# and next_token has to be 1 after the call
		if not self._parser or self._next_token <= 1: return None
		self._next_token -= 1
		return self._tokens[self._next_token - 1]


class ParserController:
	def __init__(self):
		parsers = {}
		for path in iglob("./plugins/*.py"):
			dir, name = os.path.split(path)
			parser_mod = imp.load_source(name, path)
			try:
				parsers.update(parser_mod.get_parsers())
			except AttributeError:
				logger.info("ParserController: Ignored file " + path)
			except TypeError:
				logger.warning("TypeError when updating dict: " + path)
		self._parsers = parsers

	def parser_names(self):
		return sorted(self._parsers.keys())

	def get_parser(self, name, text):
		file = StringIO(text)
		parser = self._parsers[name]
		return parser(file)
